import yaml
import logging
import time
import os
import json

import requests
from openai import OpenAI
from requests.auth import HTTPBasicAuth

from csagent.core.config.schema import AgentConfig, ShortTermConfig, ModelConfig
from csagent.core.context import AgentState
from csagent.core.constants import default_short_memory_prompt, cs_short_memory_prompt

logger = logging.getLogger()

def load_agent_conf(config_path: str) -> AgentConfig:
        """从YAML配置文件创建Agent"""
        with open(config_path) as f:
            config_data = yaml.safe_load(f)
        config = AgentConfig(**config_data)
        return config

def evaluate_expression(expression: str, context: AgentState):
    """
    计算表达式在给定上下文中的结果（不限制内置函数）

    参数:
        expression: 要计算的表达式字符串
        context: 包含变量值的字典

    返回:
        表达式计算结果

    注意: 此实现不限制内置函数，存在安全风险，仅适用于可信输入环境
    """
    try:
        # 使用globals参数传入内置函数，locals参数传入用户上下文
        result = eval(expression, {'__builtins__': __builtins__}, context)
        return result
    except Exception as e:
        raise Exception(f"表达式计算错误: {e}")

def default_short_memory(context: AgentState, short_term_config: ShortTermConfig):
    user_id = context.get('user_id', '')
    session_id = context.get('session_id', '')
    log_id = context.get('log_id', '')
    messages = context.get('messages', [])
    last_short_memory = context.get('short_term_memory', {})
    message_str = ''
    for message in messages:
        role = message.get('role', '')
        content = message.get('content', '')
        if not role or role not in ['user', 'assistant']:
            continue
        if not content:
            continue
        if isinstance(content, str):
            message_str += f"{role}:{content}\n"
        elif isinstance(content, list):
            message_str += f"{role}:{content[0].get('text', '')}\n"
        else:
            continue
    cur_response = ''
    if messages and messages[-1].get('role', '') == 'assistant':
        cur_response = messages[-1].get('content', '')
    client = OpenAI(
        api_key=os.getenv("CS_MEMORY_API_KEY"),
        base_url=os.getenv("CS_MEMORY_BASE_URL"),
    )
    render_prompt = cs_short_memory_prompt.replace("[history]", message_str).replace("[response]", cur_response).replace("[pre_reverse_question_direction]", last_short_memory.get('reverse_question_direction',''))
    logger.info(f"短期记忆开始生成:%s" % json.dumps({'user_id':user_id, 
        'session_id':session_id, 'log_id':log_id, 'prompt':render_prompt}, 
        ensure_ascii=False))
    short_memory = {}
    try:
        completion = client.chat.completions.create(
            model=os.getenv("CS_MEMORY_MODEL", 'qwen2.5-7b-instruct'),
            messages=[
                {"role": "user", "content": render_prompt},
            ],
        )
        logger.info(f"短期记忆生成结果:%s" % json.dumps({'user_id':user_id, 'session_id':session_id, 'log_id':log_id, 'completion':completion.model_dump()}, ensure_ascii=False))
        res = completion.choices[0].message.content
        start = res.find('{')
        end = res.rfind('}')
        if start != -1 and end != -1 and start < end:
            res = res[start:end + 1]
        short_memory = json.loads(res)
    except Exception as e:
        logger.warning(f"短期记忆生成错误:%s" % json.dumps({'user_id':user_id, 'session_id':session_id, 'log_id':log_id, 'err':str(e)}, ensure_ascii=False))
        return short_memory
    return short_memory


class HttpES7:
    """
    ES信息检索
    """

    def __init__(self, url, username, password):
        self.es_url = url
        self.username = username
        self.password = password
        self.auth = HTTPBasicAuth(self.username, self.password)
        self.headers = {"Content-Type": "application/json"}

    def _send_request(self, method, endpoint, data=None, params=None):
        """
        发送HTTP请求到Elasticsearch
        """
        url = f"{self.es_url}/{endpoint}"
        try:
            response = requests.request(
                method,
                url,
                auth=self.auth,
                headers=self.headers,
                json=data,
                params=params,
                verify=False,
                timeout=10
            )
            response.raise_for_status()  # 检查HTTP状态码
            return response.json()
        except requests.exceptions.RequestException as e:
            logger.error(f"HTTP request error: {str(e)}")
            raise Exception(f"HTTP request error: {str(e)}")
        
    def search(self, index, data):
        """
        插入01bot_doc_label数据
        """
        endpoint = f"{index}/_search"
        res = self._send_request("POST", endpoint, data=data)
        return res
    
    def ping(self):
        auth = HTTPBasicAuth(self.username, self.password)
        try:
            response = requests.get(self.es_url, auth=auth, timeout=5)
            if response.status_code == 200:
                return True
            else:
                return False
        except requests.exceptions.RequestException as e:
            return False
        